home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks '96 / Cleanup By / Sources / CleanupBy.c next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  8.0 KB  |  420 lines  |  [TEXT/KAHL]

  1. #include <Aliases.h>
  2. #include <Traps.h>
  3. #include <SetUpA4.h>
  4.  
  5. typedef pascal long (*PPMenuSelect)(Point);
  6.  
  7. PPMenuSelect    oldMenuSelect;
  8. Str255            cleanupMenuItemName, cleanupMenuName, cleanupMenuPrefix,
  9.                         cleanupDT;
  10. Str255            cleanupDesktopName;
  11. long            menuCommands[10];
  12. short            menuCmdNbr = 0;
  13. short            prefixItems, curViewBy;
  14. short            menuID;
  15. AliasHandle        myFile;
  16.  
  17. typedef struct {
  18.     WindowPtr    theWindow;
  19.     RgnHandle    visRgn;
  20. } WindowVisRgn;
  21.  
  22. WindowVisRgn**    wVis;
  23.  
  24. pascal long MyMenuSelect(Point pt);
  25. pascal void MyEraseRect(Rect*);
  26. pascal void MyEraseRgn(RgnHandle);
  27. pascal void MyBeginUpdate(WindowPtr);
  28. pascal void MyEndUpdate(WindowPtr);
  29. void DoAbout(void);
  30.  
  31. extern pascal void ShowINIT(short id, short move);
  32.  
  33. pascal void main(void)
  34. {
  35.     Handle        me;
  36.     THz            cZone;
  37.     FCBPBRec    fcb;
  38.     FSSpec        fss;
  39.     Str31        name;
  40.     
  41.     RememberA0();
  42.     asm {
  43.         RecoverHandle
  44.         Move.L    A0,me
  45.     }
  46.     SetUpA4();
  47.     
  48.     DetachResource(me);
  49.     
  50.     fcb.ioFCBIndx = 0;
  51.     fcb.ioVRefNum = 0;
  52.     fcb.ioRefNum = CurResFile();
  53.     fcb.ioNamePtr = name;
  54.     
  55.     PBGetFCBInfoSync(&fcb);
  56.     
  57.     fss.vRefNum = fcb.ioFCBVRefNum;
  58.     fss.parID = fcb.ioFCBParID;
  59.     BlockMove(name, fss.name, 1 + name[0]);
  60.     
  61.     cZone = GetZone();
  62.     SetZone(SystemZone());
  63.     
  64.     wVis = (WindowVisRgn**) NewHandle(0);
  65.     
  66.     NewAlias(nil, &fss, &myFile);
  67.     HNoPurge((Handle) myFile);
  68.     HUnlock((Handle) myFile);
  69.     
  70.     SetZone(cZone);
  71.     
  72.     me = Get1Resource('STR ', 128);
  73.     if (me)
  74.     {
  75.         BlockMove(*me, cleanupMenuItemName, sizeof(Str255));
  76.         ReleaseResource(me);
  77.     }
  78.     
  79.     me = Get1Resource('STR ', 129);
  80.     if (me)
  81.     {
  82.         BlockMove(*me, cleanupMenuName, sizeof(Str255));
  83.         ReleaseResource(me);
  84.     }
  85.     
  86.     me = Get1Resource('STR ', 130);
  87.     if (me)
  88.     {
  89.         BlockMove(*me, cleanupDesktopName, sizeof(Str255));
  90.         ReleaseResource(me);
  91.     }
  92.     
  93.     me = Get1Resource('STR ', 131);
  94.     if (me)
  95.     {
  96.         BlockMove(*me, cleanupMenuPrefix, sizeof(Str255));
  97.         ReleaseResource(me);
  98.     }
  99.     
  100.     me = Get1Resource('STR ', 132);
  101.     if (me)
  102.     {
  103.         BlockMove(*me, cleanupDT, sizeof(Str255));
  104.         ReleaseResource(me);
  105.     }
  106.     
  107.     oldMenuSelect = (void*) GetToolTrapAddress(_MenuSelect);
  108.     SetToolTrapAddress((void*) StripAddress((Ptr) MyMenuSelect), _MenuSelect);
  109.     
  110.     ShowINIT(128, -1);
  111.     
  112.     RestoreA4();
  113. }
  114.  
  115. typedef pascal Boolean (*PPGNE)(short, EventRecord*);
  116.  
  117. PPGNE    oldGNE;
  118.  
  119. pascal Boolean MyGNE(short mask, EventRecord* evt)
  120. {
  121.     Boolean        retVal;
  122.     
  123.     SetUpA4();
  124.     
  125.     retVal = false; //(*oldGNE)(mask, evt);
  126.     if (!retVal && (mask & mDownMask))
  127.     {
  128.         evt->what = mouseDown;
  129.         evt->message = 0;
  130.         evt->when = TickCount();
  131.         evt->where.h = 300;
  132.         evt->where.v = 0;
  133.         evt->modifiers = optionKey;
  134.         retVal = true;
  135.     }
  136.     
  137. Exit:
  138.     RestoreA4();
  139.     
  140.     return retVal;
  141. }
  142.  
  143. Ptr        oldEraseRect, oldEraseRgn, oldBeginUpdate;
  144.  
  145. pascal void MyEraseRect(Rect* r)
  146. {
  147. }
  148.  
  149. pascal void MyEraseRgn(RgnHandle rgn)
  150. {
  151. }
  152.  
  153. pascal void MyBeginUpdate(WindowPtr wp)
  154. {
  155.     THz                cZone;
  156.     WindowVisRgn    wvr;
  157.     
  158.     SetUpA4();
  159.     
  160.     wvr.theWindow = wp;
  161.     wvr.visRgn = wp->visRgn;
  162.     
  163.     cZone = GetZone();
  164.  
  165.     SetZone(HandleZone((Handle) wp->visRgn));
  166.     wp->visRgn = NewRgn();
  167.     
  168.     SetZone(SystemZone());
  169.     
  170.     PtrAndHand(&wvr, (Handle) wVis, sizeof(WindowVisRgn));
  171.     
  172.     SetZone(cZone);
  173.     
  174.     RestoreA4();
  175. }
  176.  
  177. pascal void MyEndUpdate(WindowPtr wp)
  178. {
  179.     THz                cZone, hZone;
  180.     WindowVisRgn    *wvr;
  181.     long            numEnt;
  182.     
  183.     SetUpA4();
  184.     
  185.     cZone = GetZone();
  186.     numEnt = GetHandleSize((Handle) wVis) / sizeof(WindowVisRgn);
  187.     wvr = *wVis;
  188.     
  189.     while (numEnt--)
  190.     {
  191.         if (wvr->theWindow == wp)
  192.         {
  193.             SetZone(HandleZone((Handle) wp->visRgn));
  194.             DisposeRgn(wp->visRgn);
  195.             wp->visRgn = wvr->visRgn;
  196.             
  197.             SetZone(SystemZone());
  198.             Munger((Handle) wVis, (Ptr) wvr - (Ptr) *wVis, nil, sizeof(WindowVisRgn),
  199.                     wvr,  0);
  200.             SetZone(cZone);
  201.             break;
  202.         }
  203.         ++wvr;
  204.     }
  205.     
  206.     RestoreA4();
  207. }
  208.  
  209. typedef struct {
  210.     MenuHandle    menuOH;
  211.     short        menuLeft;
  212. } ItemMenu;
  213.  
  214. typedef struct {
  215.     short    lastMenu;
  216.     short    lastRight;
  217.     short    mbResID;
  218.     ItemMenu    menuInfo[1];    // only need information on the Apple & File menus
  219. } MyMenuListRec;
  220.  
  221. MenuHandle GetIndMHandle(short i)
  222. {
  223.     MyMenuListRec*    mlr = (MyMenuListRec*) *LMGetMenuList();
  224.     
  225.     if (mlr->lastMenu < (&mlr->menuInfo[i - 1] - &mlr->menuInfo[0]))
  226.         return nil;
  227.     
  228.     return mlr->menuInfo[i - 1].menuOH;
  229. }
  230.  
  231. MenuHandle BuildCleanupMenu(MenuHandle viewMenu)
  232. {
  233.     MenuHandle    mh;
  234.     short        i, baseItem, numItems;
  235.     Str255        s;
  236.     
  237.     menuID = 1;
  238.     while (GetMHandle(menuID))
  239.         ++menuID;
  240.     
  241.     mh = NewMenu(menuID, cleanupMenuName);
  242.     
  243.     (**mh).menuProc = GetResource('MDEF', 0);
  244.     CalcMenuSize(mh);
  245.     AppendMenu(mh, cleanupMenuPrefix);
  246.     
  247.     prefixItems = CountMItems(mh);
  248.     
  249.     i = numItems = CountMItems(viewMenu);    // find a dash line or first item
  250.     
  251.     do {
  252.         GetItem(viewMenu, i, s);
  253.         if (*(short*) &s[0] == '\x01-')
  254.             break;
  255.         --i;
  256.     }
  257.     while (i > 0);
  258.     
  259.     baseItem = i;
  260.     
  261.     i += 3;                // start with the third item in the menu -- by Name
  262.     
  263.     while (i <= numItems)
  264.     {
  265.         GetItem(viewMenu, i++, s);
  266.         AppendMenu(mh, s);
  267.     }
  268.     
  269.     if (!((**viewMenu).enableFlags & (1L << 0)))    // View menu disabled...
  270.         goto DisableItems;
  271.     
  272.     GetItemMark(viewMenu, curViewBy = baseItem + 1, &i);    // is "by Small Icon" selected?
  273.     if (i != noMark)
  274.         goto LeaveItemsEnabled;
  275.     
  276.     GetItemMark(viewMenu, curViewBy = baseItem + 2, &i);    // is "by Icon" selected?
  277.     if (i != noMark)
  278.         goto LeaveItemsEnabled;
  279.     
  280. DisableItems:
  281.     curViewBy = 0;
  282.     
  283.     i = prefixItems + 1;
  284.     
  285.     numItems = CountMItems(mh);
  286.     
  287.     while (i <= numItems)
  288.         DisableItem(mh, i++);
  289.     
  290. LeaveItemsEnabled:
  291.     return mh;
  292. }
  293.  
  294. pascal long MyMenuSelect(Point pt)
  295. {
  296.     long        retVal;
  297.     Boolean        removeIt;
  298.     Str255        s;
  299.     short        i, viewBy;
  300.     MenuHandle    specialMenu;
  301.     short        specialMenuID;
  302.     MenuHandle    viewMenu;
  303.     short        viewMenuID;
  304.     MenuHandle    mh;
  305.     short        mk;
  306.     
  307.     SetUpA4();
  308.     
  309.     if (EqualString(LMGetFinderName(), LMGetCurApName(), false, true))
  310.     {
  311.         Byte    b;
  312.         
  313.         if (!menuCmdNbr)
  314.         {
  315.             specialMenu = GetIndMHandle(6);
  316.             specialMenuID = (**specialMenu).menuID;
  317.             
  318.             viewMenu = GetIndMHandle(4);
  319.             viewMenuID = (**viewMenu).menuID;
  320.             
  321.             mh = BuildCleanupMenu(viewMenu);
  322.             
  323.             if (!((**specialMenu).enableFlags & (1L << 1)))
  324.                 DisableItem(mh, 3);        // disable Clean Up Window
  325.             
  326.             InsertMenu(mh, -1);
  327.             SetItemCmd(specialMenu, 1, hMenuCmd);
  328.             SetItemMark(specialMenu, 1, menuID);
  329.             GetItem(specialMenu, 1, s);
  330.             SetItem(specialMenu, 1, cleanupMenuItemName);
  331.             EnableItem(specialMenu, 1);
  332.  
  333.             if (EqualString(s, cleanupDesktopName, false, false))
  334.                 SetItem(mh, 3, cleanupDT);
  335.             
  336.             retVal = (*oldMenuSelect)(pt);
  337.             
  338.             SetItem(specialMenu, 1, s);
  339.             SetItemCmd(specialMenu, 1, 0);
  340.             SetItemMark(specialMenu, 1, 0);
  341.             DeleteMenu(menuID);
  342.             
  343.             if (*(short *) &retVal == menuID)
  344.             {
  345.                 switch (((short*) &retVal)[1])
  346.                 {
  347.                     case 1:            // About...
  348.                         DoAbout();
  349.                         retVal = 0;
  350.                         break;
  351.                     case 3:            // Clean Up Window
  352.                         retVal = ((long) specialMenuID << 16) | 1L;
  353.                         break;
  354.                     default:        // View menu items
  355.                         *(short*) &retVal = viewMenuID;
  356.                         retVal -= prefixItems - 2;
  357.                         menuCommands[menuCmdNbr++] = ((long) specialMenuID << 16) | 1L;
  358.                         menuCommands[menuCmdNbr++] = ((long) viewMenuID << 16) |
  359.                                 curViewBy;
  360.                 
  361.                         oldGNE = (void*) GetToolTrapAddress(_GetNextEvent);
  362.                         SetToolTrapAddress((void*) MyGNE, _GetNextEvent);
  363.                         oldEraseRect = (Ptr) GetToolTrapAddress(_EraseRect);
  364.                         SetToolTrapAddress((void*) MyEraseRect, _EraseRect);
  365.                         oldEraseRgn = (Ptr) GetToolTrapAddress(_EraseRgn);
  366.                         SetToolTrapAddress((void*) MyEraseRgn, _EraseRgn);
  367.                         oldBeginUpdate = (Ptr) GetToolTrapAddress(_BeginUpDate);
  368.                         SetToolTrapAddress((void*) MyBeginUpdate, _BeginUpDate);
  369.                         break;
  370.                 }
  371.             }
  372.         }
  373.         else
  374.         {
  375.             retVal = menuCommands[--menuCmdNbr];
  376.             
  377.             if (!menuCmdNbr && oldGNE)
  378.             {
  379.                 SetToolTrapAddress((void*) oldGNE, _GetNextEvent);
  380.                 oldGNE = nil;
  381.                 SetToolTrapAddress((void*) oldEraseRect, _EraseRect);
  382.                 SetToolTrapAddress((void*) oldEraseRgn, _EraseRgn);
  383.                 SetToolTrapAddress((void*) oldBeginUpdate, _BeginUpDate);
  384.             }
  385.         }
  386.     }
  387.     else
  388.         retVal = (*oldMenuSelect)(pt);
  389.     
  390.     RestoreA4();
  391.     
  392.     return(retVal);
  393. }
  394.  
  395. void DoAbout(void)
  396. {
  397.     FSSpec        fss;
  398.     Boolean        chg;
  399.     short        cResFile = CurResFile();
  400.     short        extFile;
  401.     
  402.     ResolveAlias(nil, myFile, &fss, &chg);
  403.     
  404.     extFile = FSpOpenResFile(&fss, fsCurPerm);
  405.     
  406.     if (extFile == -1)
  407.     {
  408.         UseResFile(cResFile);
  409.         SysBeep(10);
  410.         return;
  411.     }
  412.     
  413.     UseResFile(extFile);
  414.     
  415.     Alert(128, nil);
  416.     
  417.     CloseResFile(extFile);
  418.     
  419.     UseResFile(cResFile);
  420. }